package com.longchat.utils.excel.util;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.longchat.domain.upload.Express;
import com.longchat.utils.Constant;
import com.longchat.utils.Utils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
*
 * 生成应用的下载文件
 *
*/
public class DownExcel{
    private static DownExcel downExcel=null;
    private final Logger log= LoggerFactory.getLogger(DownExcel.class);
    private DownExcel(){
    }
    public static DownExcel getInstall(){
        synchronized(DownExcel.class){
            if(downExcel==null){
                downExcel=new DownExcel();
            }
        }
        //}
        return downExcel;
    }

    /**
     * <分析Excel，组装显示在页面中>
     *
     * @param: @param uploadFileFileName
     * @param: @param directory
     * @param: @param tip 1标示上传用户    2标示上传职责
     * @Date 2014-1-17 下午04:08:06
     */
    public Map<String,Object> getExpressInfOfExcel(File target,String uploadFileFileName){
        Map<String,Object> map=new HashMap<String,Object>();
        try{
            Workbook wb=null;
            if(uploadFileFileName.endsWith("xlsx")){
                try{
                    wb=new XSSFWorkbook(new FileInputStream(target));// 操作Excel2007的版本，扩展名是.xlsx
                }catch(Exception e){
                    map.put("errorBack","errorFileError");
                    log.error("分析Excel，出错 {}",e);
                    e.printStackTrace();
                }
            }else if(uploadFileFileName.endsWith("xls")){
                try{
                    wb=new HSSFWorkbook(new FileInputStream(target));// 操作Excel2003以前（包括2003）的版本，扩展名是.xls
                }catch(Exception e){
                    map.put("errorBack","errorFileError");
                    log.error("分析Excel，出错 {}",e);
                    e.printStackTrace();
                }
            }else{
                map.put("errorBack","errorFileError");
            }
            if(wb!=null){
                map=getImportListInfo(wb);
            }
        }catch(Exception e){
            log.error("分析Excel，组装显示在页面中,错误信息{}",e);
            e.printStackTrace();
        }
        return map;
    }
    /**
     * @Description: (处理excel文件数据)
     * @param: @param wb Workbook 对象
     * @param: @param tip 标示
     * @Date 2014-6-10 上午10:27:33
     */
    private Map<String,Object> getImportListInfo(Workbook wb){
        List<Object> objTList=new LinkedList<Object>();
        Map<String,Object> map=new HashMap<String,Object>();
        StringBuffer errorBack=new StringBuffer();
        StringBuffer errorBack_two=new StringBuffer();
        try{
            //多个标签 导入数据
            int tipA=0, tipC=0;
            for(int h=0;h<1;h++){//获取每个Sheet表
                int tipB=0;
                Sheet sh=wb.getSheetAt(h);
                String sheetName=sh.getSheetName();
                boolean aBool = sheetName.indexOf("ShtDictionary")!=-1,bBool= sheetName.indexOf("说明")!=-1;
                if(aBool||bBool){
                    continue;
                }
                int rowNum=sh.getLastRowNum()+1;
                if(rowNum==2){//没有数据
                    continue;
                }else{
                    //头记录
                    String tc1 = null != sh.getRow(1) ?getValueByCell(sh.getRow(1).getCell(0)) : "";
                    String tc2 = null != sh.getRow(1) ?getValueByCell(sh.getRow(1).getCell(1)) : "";

                    if (!"号码".equals(tc1) || !"ICCID".equals(tc2)) {
                        errorBack.append("对不起您导入的文件格式不正确！");
                    }

                    if(Utils.isEmptyString(errorBack)){
                        for (int i = 2; i < rowNum; i++) {
                            Row row = sh.getRow(i);
                            if(null == row){
                                continue;
                            }
                            Cell c1 = row.getCell(0); //
                            Cell c2 = row.getCell(1); //
                           
                            if(Utils.isEmptyString(getValueByCell(c1)) && Utils.isEmptyString(getValueByCell(c2))){
                                continue;
                            }

                            if (Utils.isEmptyString(getValueByCell(c1)) || Utils.isEmptyString(getValueByCell(c2))) {//判断不能为空
                                if (tipB == 0) {
                                    if (tipA > 0) {
                                        errorBack = new StringBuffer(errorBack.substring(0, errorBack.length() - 1)).append("行").append(",");
                                    }
                                    errorBack.append("sheet").append(h + 1).append("中,第").append(i + 1).append(",");
                                } else {
                                    errorBack.append(i + 1).append(",");
                                }
                                tipA++;
                                tipB++;
                                continue;
                            } else {
                                Express dto = new Express();
                                dto.setExpressName(getValueByCell(c1).trim());
                                dto.setExpressFee(getValueByCell(c2).trim());
                                objTList.add(dto);
                            }

                        }
                    }
                }
            }
        //读取sheet文件
        if(tipA>0){
            errorBack.append("行").append("_不能为空");
        }
        if(tipC>0){
            errorBack_two.append("行").append("@isValidatorError");
            //errorBack.append("@").append(errorBack_two);
            errorBack.append(errorBack_two);
        }
        //if(Constant.CARD_IMPORT.equals(tip)){
            map.put("objTList",objTList);
        //}
        //map.put("objList",objList);
        /*if(Utils.isEmpityCollection(objTList)){
            map.put("errorBack","failError");
        }else{*/
            map.put("errorBack",errorBack.toString());
        /*}*/
        }catch(Exception e){
            log.error("导入信息出错，信息{}",e);
            e.printStackTrace();
        }
        if(0 == map.size()){
            map.put("errorBack", "操作失败，请重新输入或联系管理员");
        }
        return map;
    }
    /**
     * @Description: (获取传入参数实际值)
     * @param: @param cc 待传入参数
     * @return: String    retuStr
     */
    private String getValueByCell(Cell cc){
        String retuStr="";
        if(null!=cc){
            try{
               /*CellType 类型 值
                  CELL_TYPE_NUMERIC 数值型 0
				  CELL_TYPE_STRING 字符串型 1
				  CELL_TYPE_FORMULA 公式型 2
				  CELL_TYPE_BLANK 空值 3
				  CELL_TYPE_BOOLEAN 布尔型 4
				  CELL_TYPE_ERROR 错误 5*/
                int cellType=cc.getCellType();
                if(0==cellType){
                   /* Date excelFromDate=HSSFDateUtil.getJavaDate(cc.getNumericCellValue());
                    retuStr=new DateTime(excelFromDate).toString("yyyy-MM-dd HH:mm");*/
                    retuStr=String.valueOf((long)cc.getNumericCellValue());
                }else if(1==cellType){
                    retuStr=cc.getStringCellValue();
                }else if(2==cellType){
                    retuStr=cc.getCachedFormulaResultType()+"";
                }else if(3==cellType){
                    retuStr=cc.getStringCellValue();
                }else if(4==cellType){
                    retuStr=cc.getBooleanCellValue()+"";
                }else if(5==cellType){
                    retuStr=cc.getStringCellValue();
                }
            }catch(Exception e){
                retuStr=cc.getStringCellValue();
                e.printStackTrace();
            }
            if(!Utils.isEmptyString(retuStr)){
                Pattern p=Pattern.compile("\\s*|\t|\r|\n");
                Matcher m=p.matcher(retuStr.trim());
                retuStr=m.replaceAll("");
            }
        }
        return retuStr;
    }
    
    /**
     * excel 2003版本的导出方法 支持多个sheet导出 导出的文件后缀为.xls
     *
     * @param dataMap       要导出的数据
     * @param excelFilePath excel文件的存放位置
     * @param fileName      excel文件名字
     *
     * @return
     */
    public String exportXlsExcel(Map<String,List<String[]>> dataMap,String excelFilePath,String fileName){
        FileOutputStream fout=null;
        String fileLocal="";
        try{
            File file=new File(excelFilePath);
            if(!file.exists()){
                file.mkdirs();
            }
            // 第一步，创建一个webbook，对应一个Excel文件
            HSSFWorkbook wb=new HSSFWorkbook();
            // 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
            HSSFSheet sheet=null;
            List<String[]> dataList=null;
            HSSFCellStyle style=wb.createCellStyle();
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            Set<String> keyTitle=dataMap.keySet();
            for(String title : keyTitle){
                sheet=wb.createSheet(title);
                dataList=dataMap.get(title);
                for(int i=0;null!=dataList&&i<dataList.size();i++){
                    // 生成第一行
                    HSSFRow row=sheet.createRow(i);
                    String[] arr=dataList.get(i);
                    for(int j=0;null!=arr&&j<arr.length;j++){
                        // 给这一行的第一列赋值
                        HSSFCell cell=row.createCell(j);
                        cell.setCellValue(arr[j]);
                        cell.setCellStyle(style);
                        if(i==0){
                            HSSFCellStyle tempStyle=style;
                            tempStyle.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
                            tempStyle.setFillBackgroundColor(HSSFColor.GREY_25_PERCENT.index);
                            cell.setCellStyle(tempStyle);
                        }
                    }
                }
            }
            // 第六步，将文件存到指定位置
            fileLocal=excelFilePath+"/"+fileName+".xls";
            fout=new FileOutputStream(fileLocal);
            wb.write(fout);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                if(fout != null) {
                    fout.close();
                }
            }catch(IOException e){
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return fileLocal;
    }
    
    /**
     * 具体下载文件
     *
     * @param response 响应的请求
     * @param filePath 文件路径
     */
    @SuppressWarnings("unused")
    private void downLoadFile(HttpServletResponse response,String filePath){
        try{
            response.reset();
            response.setContentType("application/octet-stream");
            String fileName=new File(filePath).getName();
            fileName=response.encodeURL(new String(fileName.getBytes(),"ISO8859_1"));//转码
            response.setHeader("Content-Disposition","inline; filename=\""+fileName+"\"");
            ServletOutputStream out=response.getOutputStream();
            InputStream inStream=new FileInputStream(filePath);
            //循环取出流中的数据
            byte[] b=new byte[1024];
            int len;
            while((len=inStream.read(b))>0){
                out.write(b,0,len);
            }
            response.setStatus(HttpServletResponse.SC_OK);
            response.flushBuffer();
            out.close();
            inStream.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    /**
     * 通过响应输出流实现文件下载
     *
     * @param response     响应的请求
     * @param fileLocal    文件的绝对路径 请用/斜杠表示路径
     * @param downloadName 自定义的文件名 ( 不要后缀),如果此值为空则使用时间日期做为默认的文件名
     * @param deleFile     下载完成后是否删除文件（true: 删除 , false：不删除）
     */
    public void downLoadFile(HttpServletResponse response,String fileLocal,String downloadName,boolean deleFile){
        InputStream in=null;
        OutputStream out=null;
        try{
            if(!"".equals(downloadName)){
                downloadName=downloadName+fileLocal.substring(fileLocal.lastIndexOf("."));
            }else{
                downloadName=fileLocal.substring(fileLocal.lastIndexOf("/")+1);
            }
            response.setHeader("content-disposition","attachment;filename="+URLEncoder.encode(downloadName,"UTF-8"));
            in=new FileInputStream(fileLocal);
            int len=0;
            byte buffer[]=new byte[1024];
            out=response.getOutputStream();
            while((len=in.read(buffer))>0){
                out.write(buffer,0,len);
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(in!=null){
                try{
                    //
                    in.close();
                    if(deleFile){
                        Thread.sleep(1000l);
                        File file=new File(fileLocal);
                        file.delete();
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

}